package com.yuuzai.openworld.actor;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.yuuzai.openworld.OpenWorldObject;
import com.yuuzai.openworld.framework.IControllable;
import com.yuuzai.openworld.framework.IInstantiable;
import com.yuuzai.openworld.framework.ITargetable;
import com.yuuzai.openworld.framework.movement.Controller;
import com.yuuzai.openworld.meter.Meter;

public abstract class Actor<DESC extends ActorDesc<?>> extends OpenWorldObject implements IInstantiable<DESC>, IControllable, ITargetable {

	public void updateMeters() {
		assertNotNull(this.meters);
		assertNotNull(this.metersMap);
		
		metersMap.clear();
		for (Meter meter : this.meters) {
			metersMap.put(meter.getName(), meter);
		}
	}
	
	/* Definition */

	protected DESC descriptor;
	protected Controller controller;

	protected Set<Meter> meters;
	protected Map<String, Meter> metersMap;

	public void setMeters(Set<Meter> value) {
		this.meters = value;
		assertNotNull(this.meters);
		this.updateMeters();
	}

	public Set<Meter> getMeters() {
		return Collections.unmodifiableSet(this.meters);
	}

	protected Actor() {
		this.setMeters(new HashSet<Meter>());
		metersMap = new HashMap<String, Meter>();
	}

	/* IInstantiable */

	public void setDescriptor(DESC value) {
		this.descriptor = value;
		assertNotNull(descriptor);
	}

	public DESC getDescriptor() {
		assertNotNull(descriptor);
		return this.descriptor;
	}

	/* IControllable */

	public void setController(Controller value) {
		this.controller = value;
	}

	public Controller getController() {
		return this.controller;
	}

}
